//  IDVI 1.0 source copyright 1996 Garth A. Dickie
//
//  This source is free for non-commercial use.  No warranty, etc.
//  Please acknowledge reuse by including the line:
//
//  "Based in part on IDVI 1.0 source copyright 1996 Garth A. Dickie"
//
//  in your documentation and source code.  For commercial use or
//  distribution, please contact the author.  Please also send
//  questions, comments, bug reports, or fixes.
//
//  Best Regards,
//  Garth A. Dickie
//  dickie@elastic.avid.com

package ibook.v10.idvi.display;

import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.ColorModel;
import java.awt.image.MemoryImageSource;
import java.util.Hashtable;

import ibook.v10.idvi.font.DVICharacter;

final class ScaledCharacter {
    private static ScaledCharacter  key = new ScaledCharacter( );
    private static Hashtable        cache = new Hashtable( );

    static synchronized ScaledCharacter getScaledCharacter( DVICharacter character, int scale ) {
        key.character = character;
        key.scale = scale;

        ScaledCharacter result = ( ScaledCharacter ) cache.get( key );

        if( result == null ) {
            result = key;
            result.init( );
            cache.put( key, result );
            key = new ScaledCharacter( );
        }

        return result;
    }




    private DVICharacter    character;
    private int             scale;

    private int             width;
    private int             height;
    private int             xOffset;
    private int             yOffset;

    private Toolkit         toolkit;
    private byte[ ]         scaledBits;

    private ScaledCharacter( ) {
    }

    private void init( ) {
        if( scale == 1 ) {
            width = character.getWidth( );
            height = character.getHeight( );
            xOffset = character.getXOffset( );
            yOffset = character.getYOffset( );
        } else {
            width = character.getScaledWidth( scale );
            height = character.getScaledHeight( scale );
            xOffset = character.getScaledXOffset( scale );
            yOffset = character.getScaledYOffset( scale );
        }
    }

    void getBounds( DVIRectangle bounds, int x, int y ) {
        int top  = y / scale - yOffset;
        int left = x / scale - xOffset;

        bounds.set( top, left, top + height, left + width );
    }

    Image getImage( ScaledColorScheme colorScheme, int colorIndex ) {
        if( scaledBits == null )
            prepare( );
        
        ColorModel model = colorScheme.getColorModel( colorIndex );
        MemoryImageSource source = new MemoryImageSource( width, height, model, scaledBits, 0, width );

        return toolkit.createImage( source );
    }

    private synchronized void prepare( ) {
        if( scaledBits == null ) {
            toolkit = Toolkit.getDefaultToolkit( );

            if( scale == 1 )
                scaledBits = character.getUnscaledBits( );
            else
                scaledBits = character.getScaledBits( scale, width, height );
        }
    }




    //  public methods used for the getScaledCharacter hashtable lookup.

    public int hashCode( ) {
        return character.hashCode( ) ^ scale;
    }

    public boolean equals( Object object ) {
        return object instanceof ScaledCharacter && equals(( ScaledCharacter ) object );
    }

    public boolean equals( ScaledCharacter key ) {
        return key.character == character && key.scale == scale;
    }
}
